﻿using System;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using System.IO;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using DDD.Core;
using FloatComparer = DDDTest.Helper.FloatComparer;

namespace DDDTest.Core {

    [TestClass]
    public class TestAnimationClip {
        [TestMethod]
        public void Test_New1 () {
            var clip = new AnimationClip ("Name of clip");

            Assert.AreEqual ("Name of clip", clip.Name);
            Assert.AreEqual (1.0f, clip.Speed);
            Assert.AreEqual (1.0f, clip.Weight);
            Assert.AreEqual (0, clip.ActiveInterval.Start);
            Assert.AreEqual (0, clip.ActiveInterval.End);
            Assert.AreEqual (0, clip.TrackCount);
        }

        [TestMethod]
        public void Test_SetWeight () {
            var clip = new AnimationClip ("Name of clip");
            clip.SetWeight (2);

            Assert.AreEqual (2.0f, clip.Weight);
        }

        [TestMethod]
        public void Test_SetActiveInterval () {
            var clip = new AnimationClip ("Name of clip");
            clip.SetActiveInterval (100, 200);

            Assert.AreEqual (100, clip.ActiveInterval.Start);
            Assert.AreEqual (200, clip.ActiveInterval.End);
        }


        [TestMethod]
        public void Test_AddTracking () {
            var clip = new AnimationClip ("Clip name");
            var track = new AnimationTrack (4, 1, InterpolationType.Linear);
            var node = new Node ();

            clip.AddTracker (node, "Alpha", track);
            Assert.AreEqual (1, clip.TrackCount);
            Assert.AreEqual (track, clip.GetTracker (0).SourceTrack);
        }

        [TestMethod]
        public void Test_RemoveTracking () {
            var track = new AnimationTrack (4, 1, InterpolationType.Linear);
            var clip = new AnimationClip ("Clip name");
            var node = new Node ();

            clip.AddTracker (node, "Alpha", track);
            Assert.AreEqual (1, clip.TrackCount);

            var n = clip.RemoveTracker (track);
            Assert.AreEqual (1, n);
            Assert.AreEqual (0, clip.TrackCount);
        }



        /// <summary>
        /// 再生位置の変更のテスト
        /// </summary>
        [TestMethod]
        public void Test_SetPlaybackPosition () {
            var clip = new AnimationClip ("Clip Name");
            clip.SetPlaybackPosition (100, 200);

            Assert.AreEqual (0, clip.GetPosition (100));
            Assert.AreEqual (100, clip.GetPosition (200));
            Assert.AreEqual (200, clip.GetPosition (300));
        }

        /// <summary>
        /// 再生速度の変更のテスト
        /// </summary>
        /// <remarks>
        /// アニメーションが不連続にならないようにリファレンスポイントが変更される。
        /// このメソッドは単純にSpeedを変えるだけの関数ではない。
        /// </remarks>
        [TestMethod]
        public void Test_SetSpeed2 () {
            var clip = new AnimationClip ("Clip Name");
            clip.SetPlaybackPosition (100, 200);
            clip.SetSpeed (2, 100);

            Assert.AreEqual (2, clip.Speed);
            Assert.AreEqual (0, clip.GetPosition (100));
            Assert.AreEqual (200, clip.GetPosition (200));
            Assert.AreEqual (400, clip.GetPosition (300));
        }

        [TestMethod]
        public void Test_Duration () {
            var clip = new AnimationClip ("Clip name");
            var track1 = new AnimationTrack (4, 1, InterpolationType.Linear);
            var track2 = new AnimationTrack (4, 1, InterpolationType.Linear);
            track1.SetDuration (100);
            track2.SetDuration (200);
            var node = new Node ();
            clip.AddTracker (node, "Alpha", track1);
            clip.AddTracker (node, "Alpha", track2);

            Assert.AreEqual (200, clip.Duration);
        }

        [TestMethod]
        public void Test_IsActive () {
            var clip = new AnimationClip ("Clip name");

            clip.SetActiveInterval (100, 200);
            Assert.AreEqual (false, clip.IsActive(50));
            Assert.AreEqual (true, clip.IsActive(100));
            Assert.AreEqual (false, clip.IsActive(200));
            Assert.AreEqual (false, clip.IsActive(250));

            clip.SetActiveInterval (100, 100);  // always active
            Assert.AreEqual (true, clip.IsActive(50));
            Assert.AreEqual (true, clip.IsActive(100));
            Assert.AreEqual (true, clip.IsActive(200));
            Assert.AreEqual (true, clip.IsActive (250));

        }

    }
}
